package com.nmgolden.lanxin;

import com.alibaba.fastjson.JSONObject;
import com.nmgolden.lanxin.model.AccessToken;
import com.nmgolden.lanxin.model.UserAccessToken;

/**
 * token 管理
 * 负责从蓝信获取 token，并维护 token 过期时间。在过期时重新请求token
 *
 * @author siger
 * @date 2022/5/13
 */
public class LanxinTokenManager {

    private final LanxinHttpClient mLanxinHttpClient;
    private final LanxinAppConfig mLanxinAppConfig;

    private AccessToken mAppToken;
    private AccessToken mJsApiToken;

    public LanxinTokenManager(LanxinAppConfig mLanxinAppConfig, LanxinHttpClient lanxinHttpClient) {
        this.mLanxinHttpClient = lanxinHttpClient;
        this.mLanxinAppConfig = mLanxinAppConfig;
    }

    /**
     * 无需线程安全处理
     *
     * @return 返回token
     */
    public String getAppToken() {
        if (null == mAppToken || mAppToken.isExpire() || null == mAppToken.getToken()) {
            mAppToken = getToken(getAppTokenUrl(), "appToken");
        }

        return mAppToken.getToken();
    }

    public String getJsApiToken() {
        if (null == mJsApiToken || mJsApiToken.isExpire() || null == mJsApiToken.getToken()) {
            mJsApiToken = getToken(getJsApiTokenUrl(), "jsApiToken");
        }
        return mJsApiToken.getToken();
    }

    /**
     * 获取 userToken
     *
     * @param code 免登录授权码
     * @return UserAccessToken 对象
     */
    public UserAccessToken getUserToken(String code) {
        JSONObject data = mLanxinHttpClient.get(getUserTokenUrl(code));
        String appToken = data.getString("userToken");
        int expiresIn = data.getInteger("expiresIn");
        String staffId = data.getString("staffId");
        return new UserAccessToken(appToken, expiresIn, staffId);
    }

    private AccessToken getToken(String url, String tokenKey) {
        JSONObject data = mLanxinHttpClient.get(url);
        String appToken = data.getString(tokenKey);
        int expiresIn = data.getInteger("expiresIn");
        return new AccessToken(appToken, expiresIn);
    }

    /**
     * 拼接获取app token的接口
     */
    private String getAppTokenUrl() {
        String APP_TOKEN_URL_TEMPLATE = "%s/v1/apptoken/create?grant_type=client_credential&appid=%s&secret=%s";
        return String.format(APP_TOKEN_URL_TEMPLATE, mLanxinAppConfig.getApiGateway(), mLanxinAppConfig.getAppId(), mLanxinAppConfig.getAppSecret());
    }

    /**
     * 拼接获取jsapi token的接口
     */
    private String getJsApiTokenUrl() {
        String appToken = getAppToken();
        String JS_API_TOKEN_URL_TEMPLATE = "%s/v1/jsapitoken/create?app_token=%s&user_token=%s";
        return String.format(JS_API_TOKEN_URL_TEMPLATE, mLanxinAppConfig.getApiGateway(), appToken, "");
    }

    private String getUserTokenUrl(String code) {
        String USER_TOKEN_URL_TEMPLATE = "%s/v1/usertoken/create?app_token=%s&grant_type=authorization_code&code=%s&redirect_uri=";
        return String.format(USER_TOKEN_URL_TEMPLATE, mLanxinAppConfig.getApiGateway(), getAppToken(), code);
    }
}
